# coding=utf-8

"""
@File: commons/JsonOperation.py
@Time: 2024/8/29 15:20
@Author: TangZuChao
@Describe: 数据库操作封装
"""

import json
from datetime import datetime

import jsonschema
import requests


class DateTimeEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.isoformat()
        return super().default(obj)


class JsonOperation(object):

    @staticmethod
    def test_parse_json(url):
        """
            解析 JSON 并访问其中的数据
        """
        response = requests.get(url)
        data = json.loads(response.text)
        assert data["key"] == "value"

    @staticmethod
    def test_build_json(url, json_data, headers):
        """
        作为 POST 请求的 body 发送
        :return:
        """
        response = requests.post(url, data=json.dumps(json_data), headers=headers)
        assert response.status_code == 201

    @staticmethod
    def test_validate_structure(url):
        """
        验证从 API 获取的 JSON 数据是否包含特定字段
        :return:
        """
        response = requests.get(url)
        data = json.loads(response.text)
        assert "key" in data and "value" in data["nested"]

    @staticmethod
    def test_update_json(url, json_data, headers):
        """
        修改 JSON 对象中的字段，发送更新后的 JSON 作为 PUT 请求
        :return:
        """
        response = requests.put(url, data=json.dumps(json_data), headers=headers)
        assert response.status_code == 200

    @staticmethod
    def test_delete_json_field(url, json_data, headers):
        """
        删除 JSON 对象中的字段，发送更新后的 JSON 作为 PATCH 请求
        :return:
        """
        response = requests.patch(url, data=json.dumps(json_data), headers=headers)
        assert response.status_code == 200

    @staticmethod
    def test_nested_json(url):
        """
        处理嵌套的 JSON 数据，验证嵌套字段
        :return:
        """
        response = requests.get(url)
        data = json.loads(response.text)
        assert data["nested"]["sub_key"] == "sub_value"

    @staticmethod
    def test_iterate_json_array(url):
        """
        遍历 JSON 数组中的对象，验证数组中每个对象的字段
        :return:
        """
        response = requests.get(url)
        data = json.loads(response.text)
        for item in data["items"]:
            assert "name" in item and "value" in item

    @staticmethod
    def test_serialize_date(url):
        """
        创建包含日期的 JSON 对象，使用自定义日期序列化器。
        :return:
        """
        data = {"timestamp": datetime.now()}
        headers = {"Content-Type": "application/json"}

        response = requests.post(url, data=json.dumps(data, cls=DateTimeEncoder), headers=headers)
        assert response.status_code == 201

    @staticmethod
    def test_json_dict_conversion(json_data):
        """
        将 JSON 字符串转换为字典，将字典转换回 JSON 字符串。
        :return:
        """
        json_str = json.dumps(json_data)
        parsed_data = json.loads(json_str)
        assert json_data == parsed_data

    @staticmethod
    def test_json_schema_validation(url):
        """
        使用第三方库如 jsonschema 来校验 JSON 数据，验证 JSON 数据是否符合预定义的模式。
        :return:
        """
        response = requests.get(url)
        data = json.loads(response.text)
        schema = {
            "type": "object",
            "properties": {
                "key": {"type": "string"},
                "nested": {"type": "object", "properties": {"sub_key": {"type": "string"}}},
            },
            "required": ["key", "nested"],
        }
        jsonschema.validate(instance=data, schema=schema)
